/*
 * Created on 2008-7-9
 *
 * TODO
 */
package jacky.lanlan.song.extension.struts.annotation;

import jacky.lanlan.song.closure.Factory;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

/**
 * 标示方法将被远程调用，被标注的方法的返回值会以JSON格式编码。
 * 
 * @author Jacky.Song
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface JSON {
	/**
	 * 提供一个用来编码JSON字符串的编码器。
	 * <p>
	 * 默认提供<b>JSON-Lib</b>的JSON实现。
	 */
	Class<? extends Factory<JSONEncoder>> encoder() default JSonLibFactory.class;
	
	/**
	 * JSON字符串编码器。
	 * <p>
	 * 默认内置<b>JSON-Lib</b>编码器。
	 * 
	 * @author Jacky.Song
	 */
	public interface JSONEncoder {
		
		/**
		 * 编码一个对象为JSON字符串。
		 * 
		 * @param returnValue
		 *          要编码的对象，由Struts执行方法返回
		 * @param execution
		 *          返回returnValue的执行方法
		 * @return 代表这个对象的JSON字符串
		 */
		String encode(Object returnValue, Method execution);
		
		JSONEncoder JSON_LIB_ENCODER = new JSONEncoder() {
			public String encode(Object reValue, Method execution) {
				String json = null;
				try {
					JSONObject jsonObject = JSONObject.fromObject(reValue);
					json = jsonObject.toString();
				}
				catch (Exception e) {
					// 失败，尝试JSONArray
					try {
						JSONArray array = JSONArray.fromObject(reValue);
						json = array.toString();
					}
					catch (Exception e2) {
						throw new RuntimeException("无法编码返回值 [" + reValue + "] 为JSON格式："
								+ e2);
					}
				}
				return json;
			}
		};
	}
	
	/**
	 * JSON-Lib编码器工厂，提供JSON-Lib编码器。
	 * 
	 * @author Jacky.Song
	 */
	public class JSonLibFactory implements Factory<JSONEncoder> {
		public JSONEncoder create() {
			return JSONEncoder.JSON_LIB_ENCODER;
		}
	}
	
}
